package com.bzframework.pro.authorize.configuatrion;

import com.bzframework.pro.authorize.context.ReactiveUserTokenContextHolder;
import com.bzframework.pro.authorize.service.UserService;
import com.bzframework.pro.authorize.filter.ReactiveRequestContextWebFilter;
import com.bzframework.pro.authorize.strategy.login.EmailLoginStrategy;
import com.bzframework.pro.authorize.strategy.login.LoginStrategy;
import com.bzframework.pro.authorize.strategy.login.LoginStrategyExecutor;
import com.bzframework.pro.authorize.strategy.login.PasswordLoginStrategy;
import com.bzframework.pro.authorize.token.generator.Md5PasswordGenerator;
import com.bzframework.pro.authorize.token.generator.PasswordGenerator;
import com.bzframework.pro.authorize.token.manager.RedisUserTokenManager;
import com.bzframework.pro.authorize.token.manager.UserTokenManager;
import com.bzframework.pro.authorize.token.parser.DefaultTokenParser;
import com.bzframework.pro.authorize.web.EmailController;
import com.bzframework.pro.notify.email.EmailManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.ReactiveRedisOperations;

import java.util.List;

/**
 * @Author bingzhong
 * @Date 2024/11/23 22:23
 * @Description
 */
public class AuthorizingHandlerAutoConfiguration {

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
    public ReactiveRequestContextWebFilter reactiveRequestContextFilter(DefaultTokenParser defaultTokenParser) {
        return new ReactiveRequestContextWebFilter(defaultTokenParser);
    }

    @Bean
    @ConditionalOnMissingBean
    public DefaultTokenParser defaultTokenParser() {
        return new DefaultTokenParser();
    }

    @Bean
    @ConditionalOnMissingBean
    public UserTokenManager redisUserTokenManager(ReactiveRedisOperations<String, String> redisOperations) {
        RedisUserTokenManager redisUserTokenManager = new RedisUserTokenManager(redisOperations);
        ReactiveUserTokenContextHolder.setManager(redisUserTokenManager);
        return redisUserTokenManager;
    }

    @Bean
    public PasswordGenerator tokenGenerator() {
        return new Md5PasswordGenerator();
    }
    @Bean
    public LoginStrategy passwordLoginStrategy(ReactiveRedisOperations<String, String> redisOperations,
                                               PasswordGenerator passwordGenerator,
                                               UserService userService) {
        return new PasswordLoginStrategy(redisOperations, passwordGenerator, userService);
    }

    @Bean
    public LoginStrategy emailLoginStrategy(ReactiveRedisOperations<String, String> redisOperations,
                                            PasswordGenerator passwordGenerator,
                                            UserService userService) {
        return new EmailLoginStrategy(redisOperations, passwordGenerator, userService);
    }


    @Bean
    @ConditionalOnMissingBean
    public LoginStrategyExecutor loginStrategyExecutor(List<LoginStrategy> strategies) {
        return new LoginStrategyExecutor(strategies);
    }

    @Bean
    @ConditionalOnMissingBean
    public EmailController emailController(EmailManager emailManager) {
        return new EmailController(emailManager);
    }


}
